/*
 * Copyright 2002-2010 Edward L. Stauff.                  Contact: <EdStauff@gmail.com>.
 * 
 * This file, "MultiProgressReporter.cs", is part of the "Stauffware.Common" 
 * library.
 * "Stauffware.Common" is free software: you can redistribute it and/or 
 * modify it under the terms of the GNU Lesser Public License as published by the 
 * Free Software Foundation, either version 3 of the License, or (at your option) 
 * any later version.
 * 
 * "Stauffware.Common" is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Public License for more 
 * details.
 * 
 * You should have received a copy of the GNU Lesser Public License along with 
 * the "Stauffware.Common" sources.  If not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.Collections.Generic;
using System.Text;

namespace Stauffware.Common.Core
{
	/// <summary>
	/// A progress reporter that copies its output to a list of IProgressReporters.
	/// </summary>
	/// <remarks>
	/// This class maintains its own count of errors and warnings.
	/// </remarks>

	public class MultiProgressReporter : IProgressReporter
	{
		private readonly List<IProgressReporter> Reporters = new List<IProgressReporter>();

		//---------------------------------------------------------------------

		/// Constructs a MultiProgressReporter whose output goes nowhere.
		public MultiProgressReporter ()
		{
		}

		/// Constructs a MultiProgressReporter which copies its output to the
		/// given IProgressReporter.
		public MultiProgressReporter (IProgressReporter pr)
		{
			this.Reporters.Add(pr);
		}

		//---------------------------------------------------------------------
		/// <summary>
		/// Adds the given IProgressReporter to the list.
		/// It must not already be in the list.
		/// </summary>

		public void Add (IProgressReporter pr)
		{
			Require.NotNull(pr);
			Require.Condition(!this.Reporters.Contains(pr));
			this.Reporters.Add(pr);
		}

		//---------------------------------------------------------------------
		/// <summary>
		/// Removes the given IProgressReporter from the list.
		/// </summary>
		/// <returns>whether the item was in the list</returns>

		public bool Remove (IProgressReporter pr)
		{
			return this.Reporters.Remove(pr);
		}

		//---------------------------------------------------------------------

		/// <see cref="Stauffware.Common.Core.IProgressReporter.ErrorCount"/> 
		public int ErrorCount
		{
			get { return this._errorCount; }
			set { this._errorCount = value; }
		}
		private int _errorCount = 0;

		/// <see cref="Stauffware.Common.Core.IProgressReporter.WarningCount"/> 
		public int WarningCount
		{
			get { return this._warningCount; }
			set { this._warningCount = value; }
		}
		private int _warningCount = 0;

		//---------------------------------------------------------------------

		/// <see cref="Stauffware.Common.Core.IProgressReporter.LogError"/> 
		public virtual void LogError (string descr)
		{
			foreach (IProgressReporter pr in this.Reporters)
				pr.LogError(descr);
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.LogWarning"/> 
		public virtual void LogWarning (string descr)
		{
			foreach (IProgressReporter pr in this.Reporters)
				pr.LogWarning(descr);
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.LogException(Exception)"/> 
		public virtual void LogException (Exception exc)
		{
			foreach (IProgressReporter pr in this.Reporters)
				pr.LogException(exc);
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.LogException(Exception, string)"/> 
		public virtual void LogException (Exception exc, string context)
		{
			foreach (IProgressReporter pr in this.Reporters)
				pr.LogException(exc, context);
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.LogException(Exception, string)"/> 
		public virtual void LogLine (string descr)
		{
			foreach (IProgressReporter pr in this.Reporters)
				pr.LogLine(descr);
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.Log"/> 
		public virtual void Log (string text)
		{
			foreach (IProgressReporter pr in this.Reporters)
				pr.Log(text);
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.Indent"/> 
		public virtual void Indent ()
		{
			foreach (IProgressReporter pr in this.Reporters)
				pr.Indent();
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.Outdent"/> 
		public virtual void Outdent () 
		{
			foreach (IProgressReporter pr in this.Reporters)
				pr.Outdent();
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.OutdentAll"/> 
		public virtual void OutdentAll () 
		{
			foreach (IProgressReporter pr in this.Reporters)
				pr.OutdentAll();
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.Clear"/> 
		public virtual void Clear () 
		{
			foreach (IProgressReporter pr in this.Reporters)
				pr.Clear();
		}

	}
}
